package com.cy.ppj.service.account.impl;

import com.cy.ppj.comm.constant.CacheConstants;
import com.cy.ppj.comm.utils.CommonUtils;
import com.cy.ppj.dao.mapper.account.UserOrderInfoMapper;
import com.cy.ppj.dao.mapper.user.UserInfoMapper;
import com.cy.ppj.dao.mapper.user.UserMapper;
import com.cy.ppj.model.CacheBean;
import com.cy.ppj.model.dto.account.BrokerUpgradeDTO;
import com.cy.ppj.model.dto.account.BrokerUpgradeUpdateDTO;
import com.cy.ppj.model.dto.sys.BrokerCommissionSettingsDTO;
import com.cy.ppj.model.dto.sys.TeamCommissionSettingsDTO;
import com.cy.ppj.model.enums.account.BrokerLevel;
import com.cy.ppj.model.query.account.BrokerInfoQuery;
import com.cy.ppj.model.query.account.BrokerUpgradeQuery;
import com.cy.ppj.model.vo.front.account.BrokerInfoVO;
import com.cy.ppj.model.vo.front.account.UserLoanStatisticsVO;
import com.cy.ppj.service.BaseService;
import com.cy.ppj.service.account.BrokerService;
import com.cy.ppj.service.sys.SystemSettingsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: 经纪人
 * @author: Ocean
 * @create: 2018-09-10 14:27
 **/
@Slf4j
@Service
public class BrokerServiceImpl extends BaseService implements BrokerService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SystemSettingsService systemSettingsService;
    @Autowired
    private UserOrderInfoMapper userOrderInfoMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public BrokerInfoVO queryBrokerInfo(Long userId) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int quarter = CommonUtils.getQuarter(month);

        BrokerInfoQuery query = new BrokerInfoQuery();
        query.setUserId(userId);
        query.setYear(year);
        query.setQuarter(quarter);
        query.setMonth(month);

        BrokerInfoVO brokerInfoVO = userMapper.selectBrokerInfo(query);

        //团队返佣金
        TeamCommissionSettingsDTO teamCommissionSettings = systemSettingsService.queryTeamCommissionSettingsInCache();
        brokerInfoVO.setTeamCommissionFirstRate(teamCommissionSettings.getFirstRate());
        brokerInfoVO.setTeamCommissionSecondRate(teamCommissionSettings.getSecondRate());
        brokerInfoVO.setTeamCommissionConut(brokerInfoVO.getTeamCommissionFirstConut() + brokerInfoVO.getTeamCommissionSecondConut());

        if(brokerInfoVO.getNewUser()) {
        	// 如果是新用户，还在体验期，即当前经纪人等级为‘钻石经纪人(体验)’
        	brokerInfoVO.setBrokerLevel(BrokerLevel.DIAMOND);
        	brokerInfoVO.setBrokerLevelText(brokerInfoVO.getBrokerLevel().getText() + "（体验）");
        	brokerInfoVO.setExperienceTime(CommonUtils.addTime(brokerInfoVO.getCreateTime(), 3, Calendar.MONTH));
        	
        	BrokerCommissionSettingsDTO brokerCommissionSettings = systemSettingsService.queryBrokerCommissionSettingsInCache();
        	brokerInfoVO.setBrokerCommissionRate(brokerCommissionSettings.getDiamondRate());
        	//升级到钻石经纪人所需放款金额
            BigDecimal upgradeAmount = brokerCommissionSettings.getDiamondUpgradeCondition();
            //剩余升级金额
            BigDecimal residualUpgradeAmount = upgradeAmount.subtract(brokerInfoVO.getMonthLoanAmount());
            if (residualUpgradeAmount.compareTo(BigDecimal.ZERO) <= 0) {
                residualUpgradeAmount = BigDecimal.ZERO;
            }
        	brokerInfoVO.setResidualUpgradeAmount(residualUpgradeAmount);
        	
        }else {
        	brokerInfoVO.setBrokerLevelText(brokerInfoVO.getBrokerLevel().getText());
        	// 经纪人等级信息
        	BrokerUpgradeDTO brokerUpgrade = new BrokerUpgradeDTO();
        	BeanUtils.copyProperties(brokerInfoVO, brokerUpgrade);
        	queryBrokerUpgradeInfo(brokerUpgrade);
        	BeanUtils.copyProperties(brokerUpgrade, brokerInfoVO);
        }
        
        return brokerInfoVO;
    }

    @Override
    public BrokerInfoVO queryBrokerInfo2(Long userId) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        //int quarter = CommonUtils.getQuarter(month);

        BrokerInfoQuery query = new BrokerInfoQuery();
        query.setUserId(userId);
        query.setYear(year);
        query.setMonth(month);
        //query.setQuarter(quarter);

        BrokerInfoVO brokerInfoVO = userMapper.selectBrokerInfo2(query);
        brokerInfoVO.setBrokerLevelText(brokerInfoVO.getBrokerLevel().getText());
        if(!CommonUtils.isEmpty(brokerInfoVO.getRecommendRealName())) {
            brokerInfoVO.setRecommendRealName(CommonUtils.nameFormat(brokerInfoVO.getRecommendRealName()));
        }

        return brokerInfoVO;
    }

    @Override
    @Cacheable(value = CacheConstants.CACHE_VALUE_1H, key = "'queryUserLoanStatisticsInCache-'+#userId")
    public CacheBean<UserLoanStatisticsVO> queryUserLoanMonthStatisticsInCache(Long userId, Date time) {

        //今天的开始时间
        Date endTime = CommonUtils.getDayEndTime(time);
        //半年前的时间
        Date startTime = CommonUtils.addTime(endTime, -5, Calendar.MONTH);
        //转换为当月第一天
        startTime = CommonUtils.getMonthStartTime(startTime);

        List<UserLoanStatisticsVO> list = userOrderInfoMapper.selectUserLoanMonthStatistics(userId, startTime, endTime);

        List<UserLoanStatisticsVO> tempList = new ArrayList<>();
        if (list.size() < 6) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startTime);
            int startMonth = calendar.get(Calendar.MONTH) + 1;
            int startYear = calendar.get(Calendar.YEAR);
            for (int i = 0; i < 6; i++) {
                int temp = startMonth + i;
                int month = temp > 12 ? 1 : temp;
                if (temp > 12) {
                    startYear++;
                }
                if (list.stream().noneMatch(c -> Integer.valueOf(month).equals(c.getMonth()))) {
                    UserLoanStatisticsVO userLoanStatistics = new UserLoanStatisticsVO();
                    userLoanStatistics.setLoanAmount(BigDecimal.ZERO);
                    userLoanStatistics.setYear(startYear);
                    userLoanStatistics.setMonth(month);
                    tempList.add(userLoanStatistics);
                }
            }
            list.addAll(tempList);
            list = list.stream().sorted((a, b) -> {
                if (a.getYear().equals(b.getYear())) {
                    return a.getMonth().compareTo(b.getMonth());
                } else {
                    return a.getYear().compareTo(b.getYear());
                }
            }).collect(Collectors.toList());

        }
        CacheBean<UserLoanStatisticsVO> cacheBean = new CacheBean<>();
        cacheBean.setList(list);
        cacheBean.setCacheTime(time);
        return cacheBean;
    }

    @Override
    public CacheBean<UserLoanStatisticsVO> queryUserLoanQuarterStatisticsInCache(Long userId, Date time) {

        //季度结束时间
        Date endTime = CommonUtils.getQuarterEndTime(time);
        //半年前的时间
        Date startTime = CommonUtils.addTime(endTime, -17, Calendar.MONTH);
        //转换为当月第一天
        startTime = CommonUtils.getQuarterStartTime(startTime);

        List<UserLoanStatisticsVO> list = userOrderInfoMapper.selectUserLoanQuarterStatistics(userId, startTime, endTime);

        List<UserLoanStatisticsVO> tempList = new ArrayList<>();
        if (list.size() < 6) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startTime);
            int startMonth = calendar.get(Calendar.MONTH) + 1;
            int startQuarter = CommonUtils.getQuarter(startMonth);
            int startYear = calendar.get(Calendar.YEAR);
            for (int i = 0; i < 6; i++) {
                startQuarter++;
                if (startQuarter > 4) {
                    startYear++;
                }
                int tempYear = startYear;
                int tempQuarter = startQuarter > 4 ? startQuarter % 4 : startQuarter;
                System.out.println(startYear+"年"+startQuarter+"季度");
                if (list.stream().noneMatch(c -> Integer.valueOf(tempQuarter).equals(c.getQuarter())
                        && Integer.valueOf(tempYear).equals(c.getYear()))) {
                    UserLoanStatisticsVO userLoanStatistics = new UserLoanStatisticsVO();
                    userLoanStatistics.setLoanAmount(BigDecimal.ZERO);
                    userLoanStatistics.setYear(startYear);
                    userLoanStatistics.setQuarter(startQuarter);
                    tempList.add(userLoanStatistics);
                }
            }
            list.addAll(tempList);
            list = list.stream().sorted((a, b) -> {
                if (a.getYear().equals(b.getYear())) {
                    return a.getQuarter().compareTo(b.getQuarter());
                } else {
                    return a.getYear().compareTo(b.getYear());
                }
            }).collect(Collectors.toList());

        }
        CacheBean<UserLoanStatisticsVO> cacheBean = new CacheBean<>();
        cacheBean.setList(list);
        cacheBean.setCacheTime(time);
        return cacheBean;
    }

    @Override
    public void queryBrokerUpgradeInfo(BrokerUpgradeDTO brokerUpgrade) {

        //经纪人升级信息
        BrokerCommissionSettingsDTO brokerCommissionSettings = systemSettingsService.queryBrokerCommissionSettingsInCache();

        //保级金额
        BigDecimal keepAmount = null;
        //升级金额
        BigDecimal upgradeAmount = null;
        switch (brokerUpgrade.getBrokerLevel()) {
            case OFFICIAL:
                keepAmount = BigDecimal.ZERO;
                upgradeAmount = brokerCommissionSettings.getGoldenUpgradeCondition();
                brokerUpgrade.setBrokerCommissionRate(brokerCommissionSettings.getOfficalRate());
                break;

            case GOLDEN:
                keepAmount = brokerCommissionSettings.getGoldenKeepCondition();
                upgradeAmount = brokerCommissionSettings.getDiamondUpgradeCondition();
                brokerUpgrade.setBrokerCommissionRate(brokerCommissionSettings.getGoldenRate());
                break;

            case DIAMOND:
                keepAmount = brokerCommissionSettings.getDiamondKeepCondition();
                upgradeAmount = BigDecimal.ZERO;
                brokerUpgrade.setBrokerCommissionRate(brokerCommissionSettings.getDiamondRate());
                break;

            default:
                break;
        }

        //剩余保级金额
        BigDecimal residualKeepAmount = keepAmount.subtract(brokerUpgrade.getQuarterLoanAmount());
        if (residualKeepAmount.compareTo(BigDecimal.ZERO) <= 0) {
            residualKeepAmount = BigDecimal.ZERO;
        }
        //剩余升级金额
        BigDecimal residualUpgradeAmount = upgradeAmount.subtract(brokerUpgrade.getMonthLoanAmount());
        if (residualUpgradeAmount.compareTo(BigDecimal.ZERO) <= 0) {
            residualUpgradeAmount = BigDecimal.ZERO;
        }

        //是否升级
        BrokerLevel upgradeLevel = null;
        if (brokerUpgrade.getMonthLoanAmount().compareTo(brokerCommissionSettings.getDiamondUpgradeCondition()) >= 0) {
            //满足砖石升级条件
            upgradeLevel = BrokerLevel.DIAMOND;
        } else if (brokerUpgrade.getMonthLoanAmount().compareTo(brokerCommissionSettings.getGoldenUpgradeCondition()) >= 0) {
            //满足金牌升级条件
            upgradeLevel = BrokerLevel.GOLDEN;
        }

        if (brokerUpgrade.getBrokerLevel().equals(upgradeLevel)) {
            upgradeLevel = null;
        }

        brokerUpgrade.setResidualKeepAmount(residualKeepAmount);
        brokerUpgrade.setResidualUpgradeAmount(residualUpgradeAmount);
        brokerUpgrade.setUpgradeLevel(upgradeLevel);
        brokerUpgrade.setBrokerLevelText(brokerUpgrade.getBrokerLevel().getText());
    }

    @Override
    public void upgradeBrokerLevel(Long userId, Date time) {

        //计算时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int quarter = CommonUtils.getQuarter(month);

        //查询升级信息
        BrokerUpgradeQuery query = new BrokerUpgradeQuery();
        query.setUserId(userId);
        query.setYear(year);
        query.setMonth(month);
        query.setQuarter(quarter);
        BrokerUpgradeDTO brokerUpgrade = userInfoMapper.selectBrokerUpgradeInfo(query);
        queryBrokerUpgradeInfo(brokerUpgrade);

        //升级
        if (brokerUpgrade.getUpgradeLevel() != null) {
            BrokerUpgradeUpdateDTO brokerUpgradeUpdate = new BrokerUpgradeUpdateDTO();
            brokerUpgradeUpdate.setUserId(userId);
            brokerUpgradeUpdate.setUpgradeTime(time);
            brokerUpgradeUpdate.setBrokerLevel(brokerUpgrade.getBrokerLevel());
            brokerUpgradeUpdate.setUpgradeLevel(brokerUpgrade.getUpgradeLevel());
            int result = userInfoMapper.updateBrokerLevel(brokerUpgradeUpdate);
            state(result == 1, "经纪人等级升级失败");
        }
    }

    @Override
    public BigDecimal queryBrokerRate(Long userId) {

        BrokerLevel brokerLevel = userInfoMapper.queryLevelByUserId(userId);
        state(brokerLevel != null, "经纪人等级异常");

        BigDecimal brokerRate = null;

        //经纪人升级信息
        BrokerCommissionSettingsDTO brokerCommissionSettings = systemSettingsService.queryBrokerCommissionSettingsInCache();
        switch (brokerLevel) {
            case OFFICIAL:
                brokerRate = brokerCommissionSettings.getOfficalRate();
                break;

            case GOLDEN:
                brokerRate = brokerCommissionSettings.getGoldenRate();
                break;

            case DIAMOND:
                brokerRate = brokerCommissionSettings.getDiamondRate();
                break;

            default:
                break;
        }

        return brokerRate;
    }

	@Override
	public BigDecimal queryBrokerRate(BrokerLevel brokerLevel) {
		BigDecimal brokerRate = null;

        //经纪人升级信息
        BrokerCommissionSettingsDTO brokerCommissionSettings = systemSettingsService.queryBrokerCommissionSettingsInCache();
        switch (brokerLevel) {
            case OFFICIAL:
                brokerRate = brokerCommissionSettings.getOfficalRate();
                break;

            case GOLDEN:
                brokerRate = brokerCommissionSettings.getGoldenRate();
                break;

            case DIAMOND:
                brokerRate = brokerCommissionSettings.getDiamondRate();
                break;

            default:
                break;
        }

        return brokerRate;
	}
}
